﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;

namespace Marmat.Forms.Skin
{
    [Editor("Marmat.Forms.Design.TabControlUITypeEditor", typeof(System.Drawing.Design.UITypeEditor))]
    public class TabPageCollection : IList, ICollection<TabPage>
    {
        private readonly TabControl owner;
        private readonly List<TabPage> _collection;

        internal TabPageCollection(TabControl owner)
        {
            this.owner = owner;
            this._collection = new List<TabPage>();
        }

        /// <summary>
        /// 添加一个新的页签。
        /// </summary>
        /// <returns></returns>
        public TabPage Add()
        {
            return this.Add($"tabPage{this.Count + 1}");
        }

        /// <summary>
        /// 添加一个新的页签。
        /// </summary>
        /// <param name="text">页签的标题</param>
        /// <returns></returns>
        public TabPage Add(string text)
        {
            TabPage tabPage = new TabPage();
            if (text != string.Empty)
                tabPage.Text = text;
            this.Add(tabPage);
            return tabPage;
        }
        /// <summary>
        /// 将页签的实例添加到 TabControl 控件中。
        /// </summary>
        /// <param name="tabPage">待添加的页签</param>
        public void Add(TabPage tabPage)
        {
            if (!this.Contains(tabPage))
            {
                tabPage.Dock = DockStyle.Fill;
                tabPage.ImageList = this.owner.ImageList;
                tabPage.parent = this.owner;
                this.owner.Controls.Add(tabPage);
                if (this.owner.Container != null)
                    this.owner.Container.Add(tabPage);
                if (this.owner.SelectedTab != null)
                    this.owner.SelectedTab.BringToFront();
                this._collection.Add(tabPage);
                this.owner.Invalidate();
            }
        }

        /// <summary>
        /// 获取或设置指定索引处的元素。
        /// </summary>
        /// <param name="index">要获取的选项卡页的从零开始的索引。</param>
        /// <returns>位于指定索引处的 Marmat.Forms.Skin.TabPage。</returns>
        public virtual TabPage this[int index] => this._collection[index];

        /// <summary>
        /// 获取带有来自集合的指定键的选项卡页。
        /// </summary>
        /// <param name="key">要检索的选项卡页的名称。</param>
        /// <returns>具有指定键的 Marmat.Forms.Skin.TabPage。</returns>
        public virtual TabPage this[string key]
        {
            get => this._collection.First(x => x.Name == key);
        }

        /// <summary>
        /// 获取集合中选项卡页的数目。
        /// </summary>
        /// <returns>集合中选项卡页的数目。</returns>
        public int Count => this._collection.Count;

        bool IList.IsReadOnly => ((IList)this._collection).IsReadOnly;

        bool IList.IsFixedSize => ((IList)this._collection).IsFixedSize;

        object ICollection.SyncRoot => ((ICollection)this._collection).SyncRoot;

        bool ICollection.IsSynchronized => ((ICollection)this._collection).IsSynchronized;

        bool ICollection<TabPage>.IsReadOnly => ((ICollection<TabPage>)this._collection).IsReadOnly;

        object IList.this[int index] { get => ((IList)this._collection)[index]; set => ((IList)this._collection)[index] = value; }

        /// <summary>
        /// 确定指定的选项卡页是否在集合中。
        /// </summary>
        /// <param name="page">要在集合中查找的 Marmat.Forms.Skin.TabPage。</param>
        /// <returns></returns>
        public bool Contains(TabPage page)
        {
            return this._collection.Contains(page);
        }

        /// <summary>
        /// 确定集合是否包含带有指定键的选项卡页。
        /// </summary>
        /// <param name="key">要搜索的选项卡页的名称。</param>
        /// <returns>若要指示在集合中找到了带有指定键的选项卡页，则为 true；否则为 false。</returns>
        public virtual bool ContainsKey(string key)
        {
            return this._collection.Exists(page => page.Name == key);
        }

        /// <summary>
        /// 从集合中移除 Marmat.Forms.Skin.TabPage。
        /// </summary>
        /// <param name="page">要移除的 System.Windows.Forms.TabPage。</param>
        /// <returns></returns>
        public bool Remove(TabPage page)
        {
            bool result = false;
            if (this.Contains(page))
            {
                page.parent = this.owner;
                this.owner.Controls.Remove(page);
                if (this.owner.Container != null)
                    this.owner.Container.Remove(page);
                result = this._collection.Remove(page);
            }
            return result;
        }

        /// <summary>
        /// 从集合中清除所有的 Marmat.Forms.Skin.TabPage。
        /// </summary>
        public void Clear()
        {
            if (this.owner.Container != null)
            {
                foreach (IComponent component in this._collection)
                    this.owner.Container.Remove(component);
            }
            this.owner.Controls.Clear();
            this._collection.Clear();
        }

        int IList.Add(object value)
        {
            return ((IList)this._collection).Add(value);
        }

        bool IList.Contains(object value)
        {
            return ((IList)this._collection).Contains(value);
        }

        int IList.IndexOf(object value)
        {
            return ((IList)this._collection).IndexOf(value);
        }

        void IList.Insert(int index, object value)
        {
            ((IList)this._collection).Insert(index, value);
        }

        void IList.Remove(object value)
        {
            ((IList)this._collection).Remove(value);
        }

        void IList.RemoveAt(int index)
        {
            ((IList)this._collection).RemoveAt(index);
        }

        void ICollection.CopyTo(Array array, int index)
        {
            ((ICollection)this._collection).CopyTo(array, index);
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        void ICollection<TabPage>.CopyTo(TabPage[] array, int arrayIndex)
        {
            ((ICollection<TabPage>)this._collection).CopyTo(array, arrayIndex);
        }

        /// <summary>
        /// 返回一个循环访问集合的枚举器。
        /// </summary>
        /// <returns>用于循环访问集合的枚举数。</returns>
        public IEnumerator<TabPage> GetEnumerator()
        {
            return ((IEnumerable<TabPage>)this._collection).GetEnumerator();
        }
    }
}
